package com.flyqiu.flow.starter.el;


import org.springframework.context.ApplicationContext;

import javax.el.ELContext;
import javax.el.ELResolver;
import java.beans.FeatureDescriptor;
import java.util.Iterator;
import java.util.Map;

public class SpringBeanReadOnlyELResolver extends ELResolver {

    protected Map<String, Object> wrappedMap;
    protected ApplicationContext applicationContext;

    public SpringBeanReadOnlyELResolver(ApplicationContext applicationContext, Map<String, Object> map) {
        this.wrappedMap = map;
        this.applicationContext = applicationContext;
    }

    public Object getValue(ELContext context, Object base, Object property) {
        if (base != null) {
            return null;
        }
        if (!(property instanceof String key)) {
            return null;
        }
        if (!wrappedMap.containsKey(key)) {
            return null;
        }
        context.setPropertyResolved(true);
        Object object = wrappedMap.get(key);
        if (object != null) return object;
        Object bean = applicationContext.getBean(key);
        wrappedMap.put(key, bean);
        return bean;

    }

    public boolean isReadOnly(ELContext context, Object base, Object property) {
        return true;
    }

    public void setValue(ELContext context, Object base, Object property, Object value) {
        if (base != null) {
            return;
        }
        if (!(property instanceof String key)) {
            return;
        }
        if (wrappedMap.containsKey(key)) {
            throw new IllegalArgumentException("Cannot set value of '" + property + "', it's readonly!");
        }
    }

    public Class<?> getCommonPropertyType(ELContext context, Object arg) {
        return Object.class;
    }

    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object arg) {
        return null;
    }

    public Class<?> getType(ELContext context, Object arg1, Object arg2) {
        return Object.class;
    }
}
